/* ******************************************************************
 * This file is part of the escal project and distributed under the
 * terms of the GNU General Public License Version 3
 * Copyright (C) 2008 Epocher (xijiaosdq@gmail.com)
 * See COPYING file for licensing information.
 *******************************************************************/

#include "config_widget.h"
#include "escal.h"
#include <QStringListModel>
#include <QInputDialog>
#include <QMessageBox>
using namespace Escal;

BaseConfigWindow::BaseConfigWindow(QWidget *parent)
	:QWidget(parent)
{

};

void BaseConfigWindow::apply(){
	BaseConfigWidget *configWidget;
	foreach(configWidget, widgetList){
		configWidget->apply();
	}
};

bool BaseConfigWindow::isModified(){
	BaseConfigWidget *configWidget;
	foreach(configWidget, widgetList){
		if(configWidget->isModified())
			return true;
	}
	return false;
};

void BaseConfigWindow::reset(){
	BaseConfigWidget *configWidget;
	foreach(configWidget, widgetList){
		configWidget->reset();
	}
};

void BaseConfigWindow::setDefaults(){
	BaseConfigWidget *configWidget;
	foreach(configWidget, widgetList){
		configWidget->setDefault();
	}
};

void BaseConfigWindow::show(){
	reset();
	QWidget::show();
};

// *********************** BaseConfigWidget *******************************

BaseConfigWidget::BaseConfigWidget(const QString &key,
		const QString &title, QWidget *parent,
		BoolConfigWidget *depend)
	:QWidget(parent)
{
	setKey(key);
	this->setTitle(title);
	if(depend != 0){
		depend->addDepend(this);
	}
};

void BaseConfigWidget::setKey(const QString &key){
	this->key = key;
};

void BaseConfigWidget::setTitle(const QString &title){
	qDebug() << "BaseConfigWidget::setTitle()";
	setWindowTitle(title);
};


// ************************ BoolConfigWidget ******************************

BoolConfigWidget::BoolConfigWidget(const QString &key, const QString &title,
		QWidget *parent, BoolConfigWidget *depend)
	:BaseConfigWidget(key, title, parent, depend)
{
	setupUi(this);
	setTitle(title);
	connect(radioButton, SIGNAL(toggled(bool)),
			this, SLOT(buttonToggled(bool)));
};

void BoolConfigWidget::setTitle(const QString &title){
	qDebug() << "BoolConfigWidget::setTitle()";
	BaseConfigWidget::setTitle(title);
	radioButton->setText(title);
};

bool BoolConfigWidget::isModified(){
	bool formerValue = settings->value(key).toBool();
	bool value = radioButton->isChecked();
	if(value != formerValue){
		qDebug() << "modified";
		return true;
	}else{
		return false;
	}
};

void BoolConfigWidget::reset(){
	bool formerValue = settings->value(key).toBool();
	radioButton->setChecked(formerValue);
	QWidget *widget;
	foreach(widget, dependedWidgets){
		widget->setEnabled(formerValue);
	}

};

void BoolConfigWidget::setDefault(){
	bool defaultValue = settings->defaultValue(key).toBool();
	radioButton->setChecked(defaultValue);
};

void BoolConfigWidget::apply(){
	bool value = radioButton->isChecked();
	settings->setValue(key, value);
};

void BoolConfigWidget::addDepend(QWidget *widget){
	if(!dependedWidgets.contains(widget)){
		dependedWidgets.append(widget);
	}
};

void BoolConfigWidget::removeDepend(QWidget *widget){
	dependedWidgets.removeAll(widget);
};

void BoolConfigWidget::buttonToggled(bool checked){
	QWidget *widget;
	foreach(widget, dependedWidgets){
		widget->setEnabled(checked);
	}
};

// *************************** IntegerConfigWidget **************************

IntegerConfigWidget::IntegerConfigWidget(const QString &key,
		const QString &title, int range_min, int range_max,
		QString unit, QWidget *parent, BoolConfigWidget *depend)
	:BaseConfigWidget(key, title, parent, depend)
{
	setupUi(this);
	setTitle(title);
	setRange(range_min, range_max);
	setUnit(unit);
};

void IntegerConfigWidget::setTitle(const QString &text){
	BaseConfigWidget::setTitle(text);
	label->setText(text);
};

void IntegerConfigWidget::setUnit(QString unit){
	if(!unit.isEmpty()){
		spinBox->setSuffix(QString(" %s").arg(unit));
	}
};

void IntegerConfigWidget::setRange(int min, int max){
	spinBox->setMinimum(min);
	spinBox->setMaximum(max);
};

bool IntegerConfigWidget::isModified(){
	int formerValue = settings->value(key).toInt();
	int value = spinBox->value();
	if(value != formerValue){
		qDebug() << "int widget is modifi";
		return true;
	}else{
		return false;
	}
};

void IntegerConfigWidget::reset(){
	int formerValue = settings->value(key).toInt();
	spinBox->setValue(formerValue);
};

void IntegerConfigWidget::setDefault(){
	int defaultValue = settings->defaultValue(key).toInt();
	spinBox->setValue(defaultValue);
};

void IntegerConfigWidget::apply(){
	int value = spinBox->value();
	settings->setValue(key, value);
};

// ************************** ListConfigWidget *****************************

ListConfigWidget::ListConfigWidget(const QString &key, const QString &title,
		QWidget *parent, BoolConfigWidget *depend)
	:BaseConfigWidget(key, title, parent, depend)
{
	setupUi(this);
	setTitle(title);
	listModel=new QStringListModel(this);
	listView->setModel(listModel);
};

void ListConfigWidget::setTitle(const QString &text){
	BaseConfigWidget::setTitle(text);
	label->setText(text);
};


bool ListConfigWidget::isModified(){
	QStringList formerValue = settings->value(key).toStringList();
	QStringList value = listModel->stringList();
	if(value != formerValue){
		qDebug() << "list is modified";
		return true;
	}else{
		return false;
	}
};

void ListConfigWidget::reset(){
	QStringList formerValue = settings->value(key).toStringList();
	listModel->setStringList(formerValue);
};

void ListConfigWidget::setDefault(){
	QStringList defaultValue = settings->defaultValue(key).toStringList();
	listModel->setStringList(defaultValue);
};

void ListConfigWidget::apply(){
	QStringList value = listModel->stringList();
	settings->setValue(key, value);
};

void ListConfigWidget::newItem(){
	bool ok;
	QString text;
	for(;;){
		text= QInputDialog::getText(this, windowTitle(),
				QString(), QLineEdit::Normal, text, &ok);
		if(!ok){
			break;
		}
		if(text.isEmpty()){
			QMessageBox::warning(this, tr("warning"), 
					tr("You can not add a empty item."));
			continue;
		}
		else if(listModel->stringList().contains(text)){
			QMessageBox::warning(this, tr("warning"), 
					tr("The item already exists."));
			continue;
		}
		int rowCount = listModel->rowCount();
		listModel->insertRows(rowCount, 1);
		listModel->setData(listModel->index(rowCount, 0), text);
		break;
	};
};

void ListConfigWidget::editItem(){
	bool ok;
	QString text, formerText;
	QModelIndexList indexes = listView->selectionModel()->selectedRows();
	if(indexes.size()<1){
		return ;
	}
	text = formerText = listModel->data(indexes[0], Qt::DisplayRole).toString();
	for(;;){
		text= QInputDialog::getText(this, windowTitle(),
				QString(), QLineEdit::Normal, text, &ok);
		if(!ok || text == formerText){
			break;
		}
		if(text.isEmpty()){
			QMessageBox::warning(this, tr("warning"), 
					tr("You can not add a empty item."));
			continue;
		}
		else if(listModel->stringList().contains(text)){
			QMessageBox::warning(this, tr("warning"), 
					tr("The item already exists."));
			continue;
		}
		listModel->setData(indexes[0], text);
		break;
	};
};

void ListConfigWidget::removeItem(){
	QModelIndexList indexes = listView->selectionModel()->selectedRows();
	if(indexes.size()<1){
		return;
	}
	int row = indexes[0].row();
	listModel->removeRows(row, 1);
};

// ************************** StringConfigWidget *****************************

StringConfigWidget::StringConfigWidget(const QString &key, const QString &title,
		QWidget *parent, BoolConfigWidget *depend)
	:BaseConfigWidget(key, title, parent, depend)
{
	setupUi(this);
	setTitle(title);
};

void StringConfigWidget::setTitle(const QString &text){
	BaseConfigWidget::setTitle(text);
	label->setText(text);
};


bool StringConfigWidget::isModified(){
	QString formerValue = settings->value(key).toString();
	QString value = lineEdit->text();
	if(value != formerValue){
		qDebug() << "list is modified";
		return true;
	}else{
		return false;
	}
};

void StringConfigWidget::reset(){
	QString formerValue = settings->value(key).toString();
	lineEdit->setText(formerValue);
};

void StringConfigWidget::setDefault(){
	QString defaultValue = settings->defaultValue(key).toString();
	lineEdit->setText(defaultValue);
};

void StringConfigWidget::apply(){
	QString value = lineEdit->text();
	settings->setValue(key, value);
};

